package com.freesun.shop.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class ShiroConfig {

    //设置shiro连接redis连接地址
    @Value("${shiro.redis}")
    private String redisHost;

    /**
     *1.SecurityManager 安全管理器
     */
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(UserRealm realm,
                                                               TokenSessionManager sessionManager,
                                                               HashedCredentialsMatcher credentialsMatcher){

        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //realm里面设置密码验证器
        realm.setCredentialsMatcher(credentialsMatcher);
        securityManager.setRealm(realm);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }

    /**
     * 自定义Token的获取
     * @param sessionDAO
     * @return
     */
    @Bean
    public TokenSessionManager tokenSessionManager(RedisSessionDAO sessionDAO){
        TokenSessionManager tokenSessionManager = new TokenSessionManager();
        tokenSessionManager.setSessionDAO(sessionDAO);
        return tokenSessionManager;
    }

    /**
     * 将shiro的验证信息放在redis里面
     * 需要依赖第三方jar
     * 新建RedisSessionDao
     * @return
     */
    @Bean
    public RedisSessionDAO sessionDAO(RedisManager redisManager){
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager);
        return redisSessionDAO;
    }
    @Bean
    public RedisManager redisManager(){
        RedisManager redisManager=new RedisManager();
        JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(5);
        jedisPoolConfig.setMaxIdle(3);
        jedisPoolConfig.setMinIdle(2);
        redisManager.setJedisPoolConfig(jedisPoolConfig);
        //"192.168.150.131:6379"
        redisManager.setHost(redisHost);
        return redisManager;
    }
    //放行和拦截
    @Bean
    public DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition defaultShiroFilterChainDefinition= new DefaultShiroFilterChainDefinition();
        defaultShiroFilterChainDefinition.addPathDefinition("/login","anon");
        defaultShiroFilterChainDefinition.addPathDefinition("/captcha.jpg","anon");
       // defaultShiroFilterChainDefinition.addPathDefinition("/**","authc");

        //测试的时候放行所有，不用登录
        defaultShiroFilterChainDefinition.addPathDefinition("/**","anon");
        return defaultShiroFilterChainDefinition;
    }
    /**
     * 注解的权限认证
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager){
        AuthorizationAttributeSourceAdvisor sourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //sourceAdvisor.setOrder(-1000);
        sourceAdvisor.setSecurityManager(defaultWebSecurityManager);
        return sourceAdvisor;
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator daap = new DefaultAdvisorAutoProxyCreator();
        //使用cglib来生成代理类 默认为false使用jdk;
        daap.setProxyTargetClass(true);
        return daap;
    }
    /**
     * 密码匹配器
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher("MD5");
        credentialsMatcher.setHashIterations(2);
        return credentialsMatcher;
    }
}

